package ca.ericslandry.client.mvp.view;

import java.util.List;

import ca.ericslandry.client.GwtUtils;
import ca.ericslandry.client.mvp.presenter.IssueListPresenter;
import ca.ericslandry.client.mvp.presenter.IssuePresenter;
import ca.ericslandry.client.mvp.presenter.UserPresenter;
import ca.ericslandry.client.resource.MyConstants;
import ca.ericslandry.client.widget.CountDisplay;
import ca.ericslandry.shared.Constants;
import ca.ericslandry.shared.domain.Issue;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class IssueListView extends Composite implements IssueListPresenter.Display, HasSelectionHandlers<Cell>,
		ResizeHandler {
	private Button more = new Button(MyConstants.INSTANCE.more());
	private SimplePanel centerPanel = new SimplePanel();
	private FlexTable table = new FlexTable();
	private ScrollPanel scroll;
	private DockPanel panel = new DockPanel();

	public IssueListView() {
		panel.setWidth("100%");
		initWidget(panel);
		Label label = new Label(MyConstants.INSTANCE.latestIssues());
		label.setStyleName(Constants.CSS.HEADER);
		panel.add(label, DockPanel.NORTH);
		VerticalPanel innerPanel = new VerticalPanel();
		innerPanel.setWidth("100%");
		innerPanel.add(table);
		innerPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		innerPanel.add(more);
		scroll = new ScrollPanel(innerPanel);
		scroll.setStyleName("scroll");
		centerPanel.add(new HTML("Loading..."));
		panel.add(centerPanel, DockPanel.CENTER);
		table.setWidth("100%");
		table.setCellSpacing(0);
		table.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				doClick(event);
			}
		});
		Window.addResizeHandler(this);
		onWindowResized(Window.getClientWidth(), Window.getClientHeight());
	}

	public Widget asWidget() {
		return this;
	}

	@Override
	public void addIssueList(List<Issue> issueList, int startRow) {
		for (Issue issue : issueList) {
			int col = 0;
			HorizontalPanel panel = new HorizontalPanel();
			panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
			panel.setSpacing(5);
			panel.add(new CountDisplay(issue.getViewCount(), MyConstants.INSTANCE.views()));
			panel.add(new CountDisplay(0, MyConstants.INSTANCE.votes()));
			panel.add(new CountDisplay(0, MyConstants.INSTANCE.notes()));
			Widget title = IssuePresenter.getLinkViewIssue(issue);
			title.setStyleName("rcaption");
			panel.add(title);
			table.setWidget(startRow, col++, panel);
			table.setWidget(startRow, col, getCreatorWidget(issue));
			table.getFlexCellFormatter().setHorizontalAlignment(startRow, col, HasHorizontalAlignment.ALIGN_RIGHT);
			startRow++;
		}
		applyDataRowStyles();
		centerPanel.clear();
		centerPanel.add(scroll);
		onWindowResized(Window.getClientWidth(), Window.getClientHeight());
	}

	private Widget getCreatorWidget(Issue issue) {
		VerticalPanel panel = new VerticalPanel();
		panel.add(new HTML(GwtUtils.prettyDate(issue.getCreationDate())));
		HorizontalPanel byUser = new HorizontalPanel();
		byUser.add(new HTML(MyConstants.INSTANCE.by()));
		byUser.add(UserPresenter.getLinkViewUser(issue.getCreator()));
		// TODO: Should I add gravatar icon?
		panel.add(byUser);
		panel.setSpacing(5);
		panel.setStyleName("creator");
		return panel;
	}

	private void applyDataRowStyles() {
		HTMLTable.RowFormatter rf = table.getRowFormatter();
		for (int row = 0; row < table.getRowCount(); ++row) {
			if ((row % 2) != 0) {
				rf.addStyleName(row, "FlexTable-OddRow");
			} else {
				rf.addStyleName(row, "FlexTable-EvenRow");
			}
		}
	}

	private void doClick(ClickEvent event) {
		Cell cell = table.getCellForEvent(event);
		if (cell != null) {
			SelectionEvent.fire(this, cell);
		}
	}

	@Override
	public HasClickHandlers getMore() {
		return more;
	}

	@Override
	public HasSelectionHandlers<Cell> getSelectionSource() {
		return this;
	}

	@Override
	public HandlerRegistration addSelectionHandler(SelectionHandler<Cell> handler) {
		return addHandler(handler, SelectionEvent.getType());
	}

	@Override
	public void reset() {
		table.removeAllRows();
		centerPanel.clear();
		centerPanel.add(new HTML(MyConstants.INSTANCE.loading()));

	}

	@Override
	public void onResize(ResizeEvent event) {
		onWindowResized(event.getWidth(), event.getHeight());
	}

	private void onWindowResized(int width, int height) {
		int y = scroll.getAbsoluteTop();
		int newHeight = height - y - 9;
		scroll.setHeight(newHeight + "px");
	}

	@Override
	public void startProcessing() {
		GwtUtils.cursorWait();
		more.setEnabled(false);
	}

	@Override
	public void stopProcessing() {
		more.setEnabled(true);
		GwtUtils.cursorDefault();
	}

	@Override
	public void noMoreIssues() {
		Window.alert(MyConstants.INSTANCE.noMoreIssues());
	}

	@Override
	public void noIssues() {
		centerPanel.clear();
		centerPanel.add(new HTML(MyConstants.INSTANCE.nothingFound()));
	}
}